#include "ParserDelete.h"

const string ParserDelete::regexInstructionAndArguments = "\\s*([a-zA-Z]+)\\s*(.*)";
const string ParserDelete::regexArgumentDeleteSearchTerm = "\\s*(.+?)\\s*";
const string ParserDelete::regexArgumentDeleteTaskID = "\\s*([0-9]+)\\s*";
const string ParserDelete::regexArgumentDeleteDone = "\\s*done\\s*";

const string ParserDelete::regexInstructionDelete = "(delete)";

ParserDelete::ParserDelete(ParserBase* _nextParser) : ParserBase(_nextParser) {
}

bool ParserDelete::tryParse(string userCommand, PARSED_COMMAND& parsedCommand) {
	
	string instruction;
	string arguments;
	getInstructionAndArguments(userCommand, instruction, arguments);
	if (!checkInstruction(instruction)) {
		return false;
	}

	parseDelete(parsedCommand, arguments);

	return true;
}

bool ParserDelete::getInstructionAndArguments(const string& userCommand, 
										string& instruction, 
										string& arguments) {
	regex rgx(regexInstructionAndArguments);
	smatch matchResults;

	if (!regex_match(userCommand, matchResults, rgx)) {

		return false;
	}
	
	instruction = matchResults[INSTRUCTION_POS];
	if (matchResults.size() > ARGUMENTS_POS) {
		arguments = matchResults[ARGUMENTS_POS];
	}

	return true;
}

bool ParserDelete::checkInstruction(const string& instruction) {
	if (regex_match(instruction, regex(regexInstructionDelete,
									   tr1::regex_constants::icase))) {
		return true;
	}

	return false;
}

void ParserDelete::parseDelete(PARSED_COMMAND& parsedCommand,
				  const string& arguments) {
	smatch matchingResults;

	if (regex_match(arguments, matchingResults, regex(regexArgumentDeleteDone))) {
		makeParsedCommandDeleteDone(parsedCommand, matchingResults);
	}else if (regex_match(arguments, matchingResults, regex(regexArgumentDeleteTaskID))) {
		makeParsedCommandDeleteTaskID(parsedCommand, matchingResults);
	}else if (regex_match(arguments, matchingResults, regex(regexArgumentDeleteSearchTerm))) {
		makeParsedCommandDeleteSearchTerm(parsedCommand, matchingResults);
	}else {
		parsedCommand.commandType = INVALID;
		parsedCommand.errorType = parsedCommand.ERROR_FORMAT_DELETE;
	}
}

void ParserDelete::makeParsedCommandDeleteSearchTerm(PARSED_COMMAND& parsedCommand, 
										  smatch& matchingArguments) {
	parsedCommand.commandType = DELETE_SEARCHTERM;
	parsedCommand.deleteSearchTerm = matchingArguments[ARGUMENT_POS_DELETE_SEARCHTERM];
}
void ParserDelete::makeParsedCommandDeleteTaskID(PARSED_COMMAND& parsedCommand, 
										  smatch& matchingArguments) {
	parsedCommand.commandType = DELETE_TASKID;
	try {
		parsedCommand.deleteTaskID = getTaskIDFromArgument(matchingArguments[ARGUMENT_POS_DELETE_TASKID]);
	}catch (range_error&) {
		parsedCommand.commandType = INVALID;
		parsedCommand.errorType = parsedCommand.ERROR_INVALID_TASK_INDEX;
	}catch (...) {

	}
}
void ParserDelete::makeParsedCommandDeleteDone(PARSED_COMMAND& parsedCommand, 
									   smatch& matchingArguments) {
	parsedCommand.commandType = DELETE_DONE;
}